use criterion::{black_box, criterion_group, criterion_main, Criterion, BenchmarkId};
use cdb::storage::transaction::*;
use cdb::storage::page::PageManager;
use std::sync::Arc;
use tempfile::tempdir;

/// 基准测试：事务管理器性能
fn benchmark_transaction_manager(c: &mut Criterion) {
    let mut group = c.benchmark_group("transaction_manager");
    
    // 事务创建性能
    group.bench_function("transaction_creation", |b| {
        let temp_dir = tempdir().unwrap();
        let wal_path = temp_dir.path().join("bench.wal").to_string_lossy().to_string();
        let page_manager = Arc::new(PageManager::new(100));
        let tx_manager = TransactionManager::new(page_manager, wal_path).unwrap();
        
        b.iter(|| {
            let tx = tx_manager.begin_transaction(
                black_box(IsolationLevel::ReadCommitted), 
                black_box(false)
            ).unwrap();
            tx_manager.commit_transaction(tx).unwrap();
        })
    });
    
    // 并发事务性能
    for num_transactions in [10, 100, 1000].iter() {
        group.bench_with_input(
            BenchmarkId::new("concurrent_transactions", num_transactions),
            num_transactions,
            |b, &num_tx| {
                let temp_dir = tempdir().unwrap();
                let wal_path = temp_dir.path().join("bench.wal").to_string_lossy().to_string();
                let page_manager = Arc::new(PageManager::new(1000));
                let tx_manager = Arc::new(TransactionManager::new(page_manager, wal_path).unwrap());
                
                b.iter(|| {
                    let mut transactions = Vec::new();
                    
                    // 创建多个事务
                    for _ in 0..num_tx {
                        let tx = tx_manager.begin_transaction(
                            IsolationLevel::ReadCommitted, 
                            false
                        ).unwrap();
                        transactions.push(tx);
                    }
                    
                    // 提交所有事务
                    for tx in transactions {
                        tx_manager.commit_transaction(tx).unwrap();
                    }
                })
            },
        );
    }
    
    // 只读事务性能
    group.bench_function("readonly_transactions", |b| {
        let temp_dir = tempdir().unwrap();
        let wal_path = temp_dir.path().join("bench.wal").to_string_lossy().to_string();
        let page_manager = Arc::new(PageManager::new(100));
        let tx_manager = TransactionManager::new(page_manager, wal_path).unwrap();
        
        b.iter(|| {
            let tx = tx_manager.begin_transaction(
                black_box(IsolationLevel::ReadCommitted), 
                black_box(true) // 只读事务
            ).unwrap();
            tx_manager.commit_transaction(tx).unwrap();
        })
    });
    
    group.finish();
}

/// 基准测试：WAL管理器性能
fn benchmark_wal_manager(c: &mut Criterion) {
    let mut group = c.benchmark_group("wal_manager");
    
    // WAL写入性能
    group.bench_function("wal_write", |b| {
        let temp_dir = tempdir().unwrap();
        let wal_path = temp_dir.path().join("bench.wal").to_string_lossy().to_string();
        let wal_manager = WalManager::new(wal_path).unwrap();
        
        b.iter(|| {
            wal_manager.write_transaction_begin(black_box(1)).unwrap();
            
            let record_type = WalRecordType::Insert {
                page_id: black_box(1),
                slot_id: black_box(0),
                old_data: None,
                new_data: black_box(vec![1, 2, 3, 4, 5]),
            };
            wal_manager.write_record(black_box(1), record_type).unwrap();
            
            wal_manager.write_transaction_commit(black_box(1)).unwrap();
        })
    });
    
    // WAL刷新性能
    for buffer_size in [10, 100, 1000].iter() {
        group.bench_with_input(
            BenchmarkId::new("wal_flush", buffer_size),
            buffer_size,
            |b, &size| {
                let temp_dir = tempdir().unwrap();
                let wal_path = temp_dir.path().join("bench.wal").to_string_lossy().to_string();
                let wal_manager = WalManager::new(wal_path).unwrap();
                
                b.iter(|| {
                    // 写入多条记录
                    for i in 0..size {
                        let record_type = WalRecordType::Insert {
                            page_id: i as u64,
                            slot_id: 0,
                            old_data: None,
                            new_data: vec![1, 2, 3, 4],
                        };
                        wal_manager.write_record(i as u64, record_type).unwrap();
                    }
                    
                    // 刷新到磁盘
                    wal_manager.flush().unwrap();
                })
            },
        );
    }
    
    group.finish();
}

/// 基准测试：锁管理器性能
fn benchmark_lock_manager(c: &mut Criterion) {
    let mut group = c.benchmark_group("lock_manager");
    
    // 锁获取和释放性能
    group.bench_function("lock_acquire_release", |b| {
        let lock_manager = LockManager::new();
        
        b.iter(|| {
            let lock_id = format!("lock_{}", black_box(1));
            lock_manager.acquire_lock(
                black_box(1), 
                lock_id.clone(), 
                black_box(LockMode::Shared)
            ).unwrap();
            lock_manager.release_lock(black_box(1), &lock_id).unwrap();
        })
    });
    
    // 并发锁性能
    for num_locks in [10, 100, 1000].iter() {
        group.bench_with_input(
            BenchmarkId::new("concurrent_locks", num_locks),
            num_locks,
            |b, &num| {
                let lock_manager = LockManager::new();
                
                b.iter(|| {
                    let mut lock_ids = Vec::new();
                    
                    // 获取多个锁
                    for i in 0..num {
                        let lock_id = format!("lock_{}", i);
                        lock_manager.acquire_lock(
                            1, 
                            lock_id.clone(), 
                            LockMode::Shared
                        ).unwrap();
                        lock_ids.push(lock_id);
                    }
                    
                    // 释放所有锁
                    for lock_id in lock_ids {
                        lock_manager.release_lock(1, &lock_id).unwrap();
                    }
                })
            },
        );
    }
    
    group.finish();
}

/// 基准测试：死锁检测性能
fn benchmark_deadlock_detector(c: &mut Criterion) {
    let mut group = c.benchmark_group("deadlock_detector");
    
    // 死锁检测性能
    group.bench_function("deadlock_detection", |b| {
        let lock_manager = LockManager::new();
        let deadlock_detector = DeadlockDetector::new();
        
        b.iter(|| {
            let result = deadlock_detector.detect_deadlock(black_box(&lock_manager)).unwrap();
            black_box(result);
        })
    });
    
    // 死锁预防检查性能
    group.bench_function("deadlock_prevention", |b| {
        let deadlock_detector = DeadlockDetector::new();
        
        b.iter(|| {
            let would_deadlock = deadlock_detector.would_cause_deadlock(
                black_box(1), 
                black_box(&"test_lock".to_string())
            ).unwrap();
            black_box(would_deadlock);
        })
    });
    
    group.finish();
}

/// 基准测试：MVCC可见性检查
fn benchmark_mvcc_visibility(c: &mut Criterion) {
    let mut group = c.benchmark_group("mvcc_visibility");
    
    // 可见性检查性能
    group.bench_function("visibility_check", |b| {
        let temp_dir = tempdir().unwrap();
        let wal_path = temp_dir.path().join("bench.wal").to_string_lossy().to_string();
        let page_manager = Arc::new(PageManager::new(100));
        let tx_manager = TransactionManager::new(page_manager, wal_path).unwrap();
        
        // 创建一些已提交的事务
        for i in 1..=10 {
            let tx = tx_manager.begin_transaction(IsolationLevel::ReadCommitted, false).unwrap();
            tx_manager.commit_transaction(tx).unwrap();
        }
        
        b.iter(|| {
            // 创建只读事务并检查可见性
            let tx = tx_manager.begin_transaction(
                IsolationLevel::ReadCommitted, 
                true
            ).unwrap();
            
            // 模拟可见性检查
            let snapshot_timestamp = tx.snapshot_timestamp;
            for committed_tx_id in 1..=10 {
                let visible = committed_tx_id <= snapshot_timestamp;
                black_box(visible);
            }
            
            tx_manager.commit_transaction(tx).unwrap();
        })
    });
    
    group.finish();
}

/// 基准测试：事务统计信息
fn benchmark_transaction_stats(c: &mut Criterion) {
    let mut group = c.benchmark_group("transaction_stats");
    
    // 统计信息收集性能
    group.bench_function("stats_collection", |b| {
        let temp_dir = tempdir().unwrap();
        let wal_path = temp_dir.path().join("bench.wal").to_string_lossy().to_string();
        let page_manager = Arc::new(PageManager::new(100));
        let tx_manager = TransactionManager::new(page_manager, wal_path).unwrap();
        
        b.iter(|| {
            // 执行一些事务操作
            let tx = tx_manager.begin_transaction(IsolationLevel::ReadCommitted, false).unwrap();
            
            // 模拟一些统计信息更新
            {
                let mut stats = tx.stats.write();
                stats.rows_read += black_box(10);
                stats.rows_written += black_box(5);
                stats.locks_acquired += black_box(3);
            }
            
            tx_manager.commit_transaction(tx).unwrap();
            
            // 获取全局统计信息
            let global_stats = tx_manager.get_stats();
            black_box(global_stats);
        })
    });
    
    group.finish();
}

criterion_group!(
    benches,
    benchmark_transaction_manager,
    benchmark_wal_manager,
    benchmark_lock_manager,
    benchmark_deadlock_detector,
    benchmark_mvcc_visibility,
    benchmark_transaction_stats
);
criterion_main!(benches);
